#pragma once
#include <vector>
#include <math.h>
#include <QVector3D>
// 计数点云的最小包围盒 轴对齐包围盒AABB
class MinimumBoundBox
{
public:
    MinimumBoundBox(void);
    ~MinimumBoundBox(void);

public:
    bool calculateMinBoundingBox(const std::vector<QVector3D> &cloud);

    inline QVector3D getMinPoint() { return m_min; }
    inline QVector3D getMaxPoint() { return m_max; }
    inline QVector3D getMeanPoint() { return m_mean; }
    inline QVector3D getCenterPoint() { return m_center; }

    inline void firstPoint(QVector3D p) { m_min = m_max = m_mean = p; }
    inline float width(void) const { return m_max.x() - m_min.x(); }
    inline float height(void) const { return m_max.y() - m_min.y(); }
    inline float depth(void) const { return m_max.z() - m_min.z(); }
    float midX(void) const { return (m_min.x() + m_max.x()) / 2; }
    float midY(void) const { return (m_min.y() + m_max.y()) / 2; }
    float midZ(void) const { return (m_min.z() + m_max.z()) / 2; }
    inline void zerolize(void)
    {
        m_min = m_max = m_center = m_mean = QVector3D(0.0, 0.0, 0.0);
        index = 1;
    }
    inline void setMin(QVector3D point) { m_min = point; }
    inline void setMax(QVector3D point) { m_max = point; }

    inline bool Iszerolized()
    {
        return (abs(m_min.x()) < 0.00001 && abs(m_min.y()) < 0.00001 && abs(m_min.z()) < 0.00001 &&
                abs(m_max.x()) < 0.00001 && abs(m_max.y()) < 0.00001 && abs(m_max.z()) < 0.00001);
    }

    inline void setMinMax(float x, float &min, float &max)
    {
        if (x > max)
            max = x;
        if (x < min)
            min = x;
    }
    void setMinMax(QVector3D point, QVector3D &min, QVector3D &max);
    void nextPoint(QVector3D p);

    MinimumBoundBox &operator=(MinimumBoundBox &box);

private:
    /// 判断点是否在包围盒内
    bool isContain(QVector3D point);
    /// @brief  判断点是否有效
    /// @param point
    /// @return
    bool isValid(QVector3D point);

private:
    int index;                 // 点云中点的索引
    const float m_finvalidDis; // 无效距离的阈值，用于判断点是否有效
    QVector3D m_min;           // 包围盒的最小点坐标
    QVector3D m_max;           // 包围盒的最大点坐标
    QVector3D m_center;        // 包围盒的中心点坐标
    QVector3D m_mean;          // 包围盒的平均点坐标
};
